﻿using System;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Web.Services;
using Medianamik.Core.CodeGeneration;
using Medianamik.Core;
using Medianamik.Core.Configuration;
using Medianamik.Core.Logging;
using Medianamik.UI.Web.Services;

namespace Medianamik.UI.Services
{
    [WebService(Namespace = "http://absolunet.com/medianamik/webservices/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class MaintenanceService : WebService
    {
        private static readonly ILogger Logger = new ObjectFactory<ILogger>()
            .Get("MaintenanceServiceLogger");

        private static readonly MedianamikConfigSection Config = 
            (MedianamikConfigSection)ConfigurationManager
            .GetSection(ConfigurationSectionName.MEDIANAMIK);

        [WebMethod]
        public void RunMagicScripts()
        {
            var temp = Server.ScriptTimeout;

            try
            {
                Server.ScriptTimeout = Config.MagicScriptsTimeout;
                var allTypes = NodeTypeManager.GetAllTypes(true)
                .Where(t => t.IsGenerated)
                .OrderByDescending(t => t.Depth);

                var code = new CodeService();
                allTypes.ForEach(code.GenerateTableAndView);
                allTypes.ForEach(code.FillTable);
                code.RegenerateUserProfileView();
                Logger.Trace("Tables régénérées (scripts magiques) avec succès.");
            }
            catch (Exception ex)
            {
                Logger.Error("Erreur lors de la régénération des tables (scripts magiques).", ex);
            }
            finally
            {
                Server.ScriptTimeout = temp;
            }
        }


        [WebMethod]
        public string UpdateLocalizationAndGetVersion()
        {

            DateTime lastResourcesUpdate = DateTime.MinValue;
            ConfigManager.ReloadConfiguration();
            var configurations = ConfigManager.GetAllConfigurations();

            if (configurations.ContainsKey(MedianamikConfigurations.LastResourcesUpdateKey))
                DateTime.TryParse(configurations[MedianamikConfigurations.LastResourcesUpdateKey],
                                  out lastResourcesUpdate);

            ResourceService resourceSvc = new ResourceService();
            resourceSvc.UpdateResourcesFromService();

            return lastResourcesUpdate.ToLocalTime().ToString("F", new CultureInfo("Fr-Ca"));
        }

        [WebMethod]
        public void ResetLocalizationUpdate()
        {
            ResourceService.SetLastResourcesUpdate(new DateTime(1945,10,10));
        }


        [WebMethod]
        public void RunMagicScriptsFor(string typeName)
        {
            var temp = Server.ScriptTimeout;
            var type = NodeTypeManager.GetAllTypes(true)
                .FirstOrDefault(t => t.IsGenerated &&
                    t.Name.Equals(typeName, StringComparison.OrdinalIgnoreCase));

            try
            {
                if (type == null)
                    Logger.Error("le type " + typeName + " n'a pas été trouvé.");
                else
                {

                    Server.ScriptTimeout = Config.MagicScriptsIndividualTimeout;
                    var code = new CodeService();
                    code.DoTheMagic(type);
                    Logger.Trace("Les tables du type " + typeName + " ont été régénérées (scripts magiques) avec succès.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Erreur lors de la régénération des tables (scripts magiques). Type : " + typeName, ex);
            }
            finally
            {
                Server.ScriptTimeout = temp;
            }
        }

        [WebMethod]
        public void RegenerateUserProfileView()
        {
            try
            {
                var code = new CodeService();
                code.RegenerateUserProfileView();
            }
            catch (Exception ex)
            {
                Logger.Error("Erreur lors de la régénération de la vue UserProfile", ex);
            }
        }
    }
}
